package com.fit.utils.se;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 多线程工具
 * @author hcl
 */
public class ThreadUtil {
	private static Logger log = LoggerFactory.getLogger(ThreadUtil.class);
	
	/**
	 * 初始化线程数
	 */
	private static int INIT_THREAD_NUM = 10;
	
	/**
	 * 获取一个线程池
	 * @param threadNum
	 * @return
	 */
	public static ExecutorService getThreadPool(int threadNum){
		threadNum = threadNum < 1 ? INIT_THREAD_NUM : threadNum;
		return new ThreadPoolExecutor(threadNum, threadNum,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());
	}
	
	/**
	 * 获取一个线程池
	 * @return
	 */
	public static ExecutorService getThreadPool(){
		return getThreadPool(-1);
	}
	
	
	/**
	 * 异步的任务执行器
	 * @param task 任务
	 * @param threadPool 线程连接池
	 */
	public static void asynTaskExecutor(Runnable task,ExecutorService threadPool){
		if(task != null){
			threadPool.execute(task);
		}
	}
	
	/**
	 * 异步的任务执行器
	 * @param task 任务
	 */
	public static void asynTaskExecutor(Runnable task){
		new Thread(task).start();
	}
	
	
	/**
	 * 异步的任务执行器
	 * @param tasks 任务集合
	 * @param threadPool 线程连接池
	 */
	public static void asynTaskExecutor(List<Runnable> tasks,ExecutorService threadPool){
		for(Runnable task : tasks){
			if(task != null){
				threadPool.execute(task);
			}
		}
	}
	
	/**
	 * 异步的任务执行器
	 * @param tasks 任务集合
	 * @param threadNum 线程池初始化线程数量
	 */
	public static void asynTaskExecutor(List<Runnable> tasks,int threadNum){
		ExecutorService threadPool = getThreadPool(threadNum);
		asynTaskExecutor(tasks, threadPool);
		threadPool.shutdown();
	}
	
	
	/**
	 * 异步的任务执行器
	 * @param tasks 任务集合
	 * @param threadNum 线程池初始化线程数量
	 */
	public static void asynTaskExecutor(List<Runnable> tasks){
		asynTaskExecutor(tasks, INIT_THREAD_NUM);
	}
	
	
	
	/**
	 * 同步任务执行器(当所有任务执行完成后才会返回)
	 * @param tasks 任务集合
	 * @param threadPool 线程连接池
	 */
	public static void syncTaskExecutor(List<Runnable> tasks,ExecutorService threadPool){
		//任务执行计数器
		CountDownLatch downLatch = new CountDownLatch(tasks.size());
		for(Runnable task : tasks){
			if(task != null){
				TaskExecutor taskExecutor = new TaskExecutor(downLatch,task);
				threadPool.execute(taskExecutor);
			}
		}
		try {
			downLatch.await();
		} catch (InterruptedException e) {
			log.error("同步任务执行器,执行异常",e);
		}
	}
	
	/**
	 * 同步任务执行器(当所有任务执行完成后才会返回)
	 * @param tasks 任务集合
	 * @param threadNum 线程池初始化线程数量
	 */
	public static void syncTaskExecutor(List<Runnable> tasks,int threadNum){
		ExecutorService threadPool = getThreadPool(threadNum);
		syncTaskExecutor(tasks, threadPool);
		threadPool.shutdown();
	}
	
	/**
	 * 同步任务执行器(当所有任务执行完成后才会返回)
	 * @param tasks
	 */
	public static void syncTaskExecutor(List<Runnable> tasks){
		syncTaskExecutor(tasks, INIT_THREAD_NUM);
	}
	
	
	/**
	 * 任务执行器
	 * @author hcl
	 *
	 */
	private static class TaskExecutor implements Runnable{
		/**
		 * 任务执行计数器
		 */
		private CountDownLatch downLatch;
		
		/**
		 * 任务
		 */
		private Runnable task;
		
		/**
		 * 有参构造
		 * @param downLatch
		 * @param task
		 */
		private TaskExecutor(CountDownLatch downLatch,Runnable task) {
			this.downLatch = downLatch;
			this.task = task;
		}
		
		/**
		 * 任务执行器
		 */
		@Override
		public void run() {
			try{
				task.run();
			}finally{
				downLatch.countDown();
			}
		}
	}
	
}




